package com.godme.concurrent.pool;

import java.util.concurrent.CompletableFuture;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.Executors;
import java.util.function.Function;

public class CF {


    public void build() throws ExecutionException, InterruptedException {
        // 无返回
        CompletableFuture<Void> noneResult = CompletableFuture.runAsync(() -> System.err.println("over"));
        noneResult.get();

        // 有返回
        CompletableFuture<String> future = CompletableFuture.supplyAsync(() -> "", Executors.newSingleThreadExecutor());
        System.err.println(future.get());
    }

    public CompletableFuture<String> getFuture(){
        return CompletableFuture.supplyAsync(()->"");
    }

    public CompletableFuture<String> getFuture(String a){
        return CompletableFuture.supplyAsync(()->a);
    }

    public void then(){
        // 简单触发，无关联
        getFuture().thenRun(()-> System.err.println("over"));
        // 转换操作，连续动作
        CompletableFuture<String> future = getFuture().thenApply(Function.identity());
        // 消费操作，末尾动作
        CompletableFuture<Void> voidCompletableFuture = getFuture().thenAccept(System.err::println);
    }

    public void com() throws ExecutionException, InterruptedException {
        // 异步thenApply
        CompletableFuture<Integer> result = getFuture()
                .thenCompose(s -> CompletableFuture.supplyAsync(s::length));
        System.err.println(result);

        // 合并操作
        CompletableFuture<String> f1 = getFuture("a");
        CompletableFuture<String> f2 = getFuture("b");
        CompletableFuture<String> future = f1.thenCombine(f2, (a, b) -> a + b);
        System.err.println(future.get());
    }


    public void all() throws ExecutionException, InterruptedException {
        // all
        CompletableFuture<String> a = getFuture("a");
        CompletableFuture<String> b = getFuture("b");
        CompletableFuture<String> c = getFuture("c");
        CompletableFuture<Void> allFuture = CompletableFuture.allOf(a, b, c);
        allFuture.thenRun(()-> System.err.println("over"));

        // any
        a = getFuture("a");
        b = getFuture("b");
        c = getFuture("c");
        CompletableFuture<Object> anyFuture = CompletableFuture.anyOf(a, b, c);
        CompletableFuture<String> result = anyFuture.thenApply(Object::toString);
        System.err.println(result.get());
    }


}
